import { spawn } from "child_process";
import {
  projRoot,
  mainPackage,
  peerPackage,
  PKG_NAME,
  PKG_PREFIX,
} from "./paths";
import { buildConfig } from "./config";
// 自定义每个task的name
export const withTaskName = <T>(name: string, fn: T) =>
  Object.assign(fn, { displayName: name });

// 在node中开启一个子进程来运行脚本
export const run = async (command: string) => {
  return new Promise((resolve) => {
    // 将命令分割 例如：rm -rf 分割为['rm', '-rf'],进行解构[cmd,...args]
    const [cmd, ...args] = command.split(" ");
    const app = spawn(cmd, args, {
      cwd: projRoot,
      stdio: "inherit",
      shell: true, // 默认情况下 linux才支持 rm -rf  windows安装git bash
    });
    // 在进程已结束并且子进程的标准输入输出流已关闭之后，则触发 'close' 事件
    app.on("close", resolve); //
  });
};

export const pathRewriter = (module) => {
  const config = buildConfig[module];

  return (id: string) => {
    id = id.replace(
      new RegExp(`${PKG_PREFIX}/theme-chalk`, "g"),
      `${PKG_NAME}/theme-chalk`
    );
    id = id.replace(
      new RegExp(`${PKG_PREFIX}/`, "g"),
      `${config.bundle.path}/`
    );
    return id;
  };
};

export const getPackageManifest = (pkgPath: string) => {
  // eslint-disable-next-line @typescript-eslint/no-var-requires
  return require(pkgPath);
};

export const getPackageDependencies = (
  pkgPath: string
): Record<"dependencies" | "peerDependencies", string[]> => {
  const peerPackageFest = getPackageManifest(peerPackage);
  const manifest = getPackageManifest(pkgPath);

  return {
    dependencies: Object.keys(
      Object.assign(peerPackageFest.dependencies, manifest.dependencies)
    ),
    peerDependencies: Object.keys(
      Object.assign(peerPackageFest.peerDependencies, manifest.peerDependencies)
    ),
  };
};

export const generateExternal = async (options: { full: boolean }) => {
  const { dependencies, peerDependencies } =
    getPackageDependencies(mainPackage);

  return (id: string) => {
    const packages: string[] = peerDependencies;
    if (!options.full) {
      packages.push("@vue", ...dependencies);
    }
    return [...new Set(packages)].some(
      (pkg) => id === pkg || id.startsWith(`${pkg}/`)
    );
  };
};

export function writeBundles(bundle, options) {
  return Promise.all(options.map((option) => bundle.write(option)));
}

export const excludeFiles = (files: string[]) => {
  const excludes = ["node_modules", "test", "mock", "gulpfile", "dist"];
  return files.filter(
    (path) => !excludes.some((exclude) => path.includes(exclude))
  );
};
